﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AddIn.EA.Architecture.ComponentLogic.EAConverter
{
    public class EAConverterElement : EAConverter
    {
        public override Framework.Common.IElement ConvertObject(ElementModel.BaseModel sourceElement, Framework.Common.IElement affectedElement)
        {
            //Validate element conversion types.
            if (!(sourceElement is ElementModel.Element))
                throw new InvalidOperationException("Invalid type. The source parameter \"sourceElement\" must be \"ElementModel.Element\" type.");
            if (!(affectedElement is Framework.Package) && !(affectedElement is Framework.Element))
                throw new InvalidOperationException("Invalid type. The source parameter \"affectedElement\" must be \"AddIn.EA.Framework.Package\" type.");

            //Create the typed local elements.
            ElementModel.Element element = sourceElement as ElementModel.Element;
            Framework.Element destinationElement = null;

            //Build the EA format Element.
            if (affectedElement is Framework.Package)
            {
                Framework.Package package = affectedElement as Framework.Package;
                destinationElement = package.Elements.AddNew(element.Name, (AddIn.EA.Framework.ElementType)(int)element.Type);
            }
            else
            {
                Framework.Element elementEA = affectedElement as Framework.Element;
                destinationElement = elementEA.Elements.AddNew(element.Name, (AddIn.EA.Framework.ElementType)(int)element.Type);
            }

            if (destinationElement == null)
                throw new Exception("There was an error when creating the destination element based on the source element provided, the result destination element is null!");

            destinationElement.Abstract = element.IsAbstract ? "1" : "0";
            destinationElement.Alias = element.Alias;
            destinationElement.Notes = element.Notes;
            destinationElement.Scope = (Framework.ElementScope)Enum.Parse(typeof(Framework.ElementScope), element.Scope.ToString());
            destinationElement.Status = element.Status;
            destinationElement.Stereotype = element.Stereotype;
            destinationElement.Type = (Framework.ElementType)Enum.Parse(typeof(Framework.ElementType), element.Type.ToString());

            BindElementTaggedValues(destinationElement, element.TaggedValues);
            BindElementMethods(destinationElement, element.Methods);
            BindElementAttributes(destinationElement, element.Attributes);

            if (element.Elements != null && element.Elements.Count > 0)
            {
                foreach (ElementModel.Element itemChildElement in element.Elements)
                    ConvertObject(itemChildElement, destinationElement);
            }

            if (!String.IsNullOrEmpty(element.InheritanceClassName))
                destinationElement.AddBaseClass(element.InheritanceClassName);

            destinationElement.Update();
            destinationElement.Refresh();

            return destinationElement;
        }
        private void BindElementMethods(AddIn.EA.Framework.Element destinationElement, List<AddIn.EA.Architecture.ComponentLogic.ElementModel.Method> list)
        {
            if (list != null && list.Count > 0)
            {
                EAConverterMethod methodConverter = new EAConverterMethod();
                foreach (ElementModel.Method itemMethod in list)
                    methodConverter.ConvertObject(itemMethod, destinationElement);
            }
        }
        private void BindElementAttributes(AddIn.EA.Framework.Element destinationElement, List<AddIn.EA.Architecture.ComponentLogic.ElementModel.Attribute> list)
        {
            if (list != null && list.Count > 0)
            {
                EAConverterAttribute attributeConverter = new EAConverterAttribute();
                foreach (ElementModel.Attribute itemAttribute in list)
                    attributeConverter.ConvertObject(itemAttribute, destinationElement);
            }
        }
    }
}